package com.xjscrm.console.service.customer.chat;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xjscrm.common.annotation.MerId;
import com.xjscrm.console.chat.cache.CacheHolder;
import com.xjscrm.console.entity.ChatTalkSession;
import com.xjscrm.console.entity.ChatTalkSessionStaffRel;
import com.xjscrm.console.mapper.ChatTalkSessionStaffRelMapper;
import com.xjscrm.console.mapper.MerchatChildDeviceRelationMapper;
import com.xjscrm.console.mapper.MerchatChildMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author mingyang.chen create in 2024/3/19 14:43
 */
@Component
@Slf4j
public class ChatTalkSessionStaffRelService {

    @Autowired
    private ChatTalkSessionStaffRelMapper chatTalkSessionStaffRelMapper;
    @Autowired
    private MerchatChildDeviceRelationMapper childDeviceRelationMapper;
    @Autowired
    private MerchatChildMapper merchatChildMapper;

    @Autowired
    private CacheHolder cacheHolder;

    public void delFromConversationEnd(@MerId Long merId, Long staffId, Long deviceUniqueId, Long sessionId) {
        this.delSessionRel(merId, staffId, deviceUniqueId, sessionId);
    }

    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void delFromConversationClean(@MerId Long merId, Long staffId, Long deviceUniqueId, Long sessionId) {
        this.delSessionRel(merId, staffId, deviceUniqueId, sessionId);
    }

    public void delSessionRel(@MerId Long merId, Long staffId, Long deviceUniqueId, Long sessionId) {

        ChatTalkSessionStaffRel query = new ChatTalkSessionStaffRel();

        query.setMerId(merId);
        query.setStaffId(staffId);
        query.setDeviceUniqueId(deviceUniqueId);
        query.setTalkSessionId(sessionId);

        ChatTalkSessionStaffRel sessionStaffRel = chatTalkSessionStaffRelMapper.selectOne(query);

        if (Objects.isNull(sessionStaffRel)) {
            return;
        }
        // 删除记录
        chatTalkSessionStaffRelMapper.deleteByPrimaryKey(sessionStaffRel.getId());
        //
        refreshStaffSessionCount(merId, staffId);
    }


    public void refreshStaffSessionCount(@MerId Long merId, Long staffId) {
        int relSessionCount = chatTalkSessionStaffRelMapper.countByStaffId(merId, staffId);
        cacheHolder.setStaffSessionNowCount(merId, staffId, relSessionCount);
    }

    public ChatTalkSessionStaffRel getBySessionId(@MerId Long merId, Long staffId, Long deviceUniqueId, Long sessionId) {

        ChatTalkSessionStaffRel query = new ChatTalkSessionStaffRel();

        query.setMerId(merId);
        query.setStaffId(staffId);
        query.setDeviceUniqueId(deviceUniqueId);
        query.setTalkSessionId(sessionId);
        return chatTalkSessionStaffRelMapper.selectOne(query);
    }

    public Integer countHangWithStaffId(@MerId Long merId, Long staffId) {

        return chatTalkSessionStaffRelMapper.countHangByStaffId(merId, staffId);
    }

    public void markSessionRelExpire(@MerId Long merId, Long staffId, Long deviceUniqueId, Long sessionId) {

        ChatTalkSessionStaffRel sessionStaffRel = this.getBySessionId(merId, staffId, deviceUniqueId, sessionId);
        if (Objects.isNull(sessionStaffRel)) {
            return;
        }
        ChatTalkSessionStaffRel update = new ChatTalkSessionStaffRel();
        update.setId(sessionStaffRel.getId());
        update.setExpire(1);
        update.setExpireTime((int) (System.currentTimeMillis() / 1000L));
        chatTalkSessionStaffRelMapper.updateByPrimaryKeySelective(update);
    }

    public void markSessionRelEnd(@MerId Long merId, Long staffId, Long deviceUniqueId, Long sessionId) {

        ChatTalkSessionStaffRel sessionStaffRel = this.getBySessionId(merId, staffId, deviceUniqueId, sessionId);
        if (Objects.isNull(sessionStaffRel)) {
            return;
        }
        ChatTalkSessionStaffRel update = new ChatTalkSessionStaffRel();
        update.setId(sessionStaffRel.getId());
        update.setEnd(1);
        update.setEndTime((int) (System.currentTimeMillis() / 1000L));
        chatTalkSessionStaffRelMapper.updateByPrimaryKeySelective(update);
    }

    public List<ChatTalkSessionStaffRel> listByStaffId(@MerId Long merId, Long staffId) {

        return chatTalkSessionStaffRelMapper.selectListByStaffId(merId, staffId);
    }

    public List<ChatTalkSessionStaffRel> pageByStaffId(@MerId Long merId, Long staffId, Page<ChatTalkSessionStaffRel> page) {

        return chatTalkSessionStaffRelMapper.selectPageByStaffId(page, merId, staffId);
    }

    public List<ChatTalkSessionStaffRel> listEndByStaffId(@MerId Long merId, Long staffId) {

        return chatTalkSessionStaffRelMapper.selectListByStaffIdWithEnd(merId, staffId);
    }

    public List<ChatTalkSessionStaffRel> listByStaffIdAndDeviceUniqueId(@MerId Long merId, Long deviceUniqueId, Long staffId) {

        return chatTalkSessionStaffRelMapper.selectListByStaffIdAndDeviceUniqueId(merId, deviceUniqueId, staffId);
    }

    public List<ChatTalkSessionStaffRel> pageByStaffIdAndDeviceUniqueId(@MerId Long merId, Long deviceUniqueId, Long staffId, Page<ChatTalkSessionStaffRel> page) {

        return chatTalkSessionStaffRelMapper.selectPageByStaffIdAndDeviceUniqueId(page, merId, deviceUniqueId, staffId);
    }

    public List<ChatTalkSessionStaffRel> pageByCondition(ChatTalkSessionStaffRel query, Page<ChatTalkSessionStaffRel> page) {

        return chatTalkSessionStaffRelMapper.selectPageByCondition(page, query);
    }

    public List<ChatTalkSessionStaffRel> listBySessionIds(@MerId Long merId, Long staffId, List<Long> sessionIds) {
        if (ObjectUtils.isEmpty(sessionIds) || Objects.isNull(merId) || Objects.isNull(staffId)) {
            return Lists.newArrayList();
        }
        return chatTalkSessionStaffRelMapper.selectListBySessionIds(merId, staffId, sessionIds);
    }

    public List<Long> listIdsBySessionIds(@MerId Long merId, Long staffId, List<Long> sessionIds) {
        List<ChatTalkSessionStaffRel> talkSessionStaffRelList = this.listBySessionIds(merId, staffId, sessionIds);
        if (ObjectUtils.isEmpty(talkSessionStaffRelList)) {
            return Lists.newArrayList();
        }
        return talkSessionStaffRelList.stream().map(ChatTalkSessionStaffRel::getTalkSessionId).collect(Collectors.toList());
    }

    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void addIfAbsent(@MerId Long merId, ChatTalkSession talkSession, Long staffId) {

        ChatTalkSessionStaffRel param = new ChatTalkSessionStaffRel();
        param.setMerId(merId);
        param.setTalkSessionId(talkSession.getId());
        param.setStaffId(staffId);
        param.setDeviceUniqueId(talkSession.getDeviceUniqueId());
        ChatTalkSessionStaffRel talkSessionStaffRel = chatTalkSessionStaffRelMapper.selectOne(param);

        if (Objects.isNull(talkSessionStaffRel)) {
            ChatTalkSessionStaffRel sessionStaffRel = new ChatTalkSessionStaffRel();
            BeanUtils.copyProperties(talkSession, sessionStaffRel);

            sessionStaffRel.setId(IdUtil.getSnowflakeNextId());
            sessionStaffRel.setMerId(merId);
            sessionStaffRel.setStaffId(staffId);
            sessionStaffRel.setTalkSessionId(talkSession.getId());
            sessionStaffRel.setExpire(0);
            sessionStaffRel.setCreateTime((int) (System.currentTimeMillis() / 1000L));
            sessionStaffRel.setLastTalkTime((int) (System.currentTimeMillis() / 1000L));

            chatTalkSessionStaffRelMapper.insertSelective(sessionStaffRel);
        }
        //
        refreshStaffSessionCount(merId, staffId);
    }

    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void addIfAbsentV1(@MerId Long merId, ChatTalkSession talkSession, Long staffId, Boolean auto) {

        ChatTalkSessionStaffRel param = new ChatTalkSessionStaffRel();
        param.setMerId(merId);
        param.setTalkSessionId(talkSession.getId());
        param.setStaffId(staffId);
        param.setDeviceUniqueId(talkSession.getDeviceUniqueId());
        ChatTalkSessionStaffRel talkSessionStaffRel = chatTalkSessionStaffRelMapper.selectOne(param);

        if (Objects.isNull(talkSessionStaffRel)) {
            ChatTalkSessionStaffRel sessionStaffRel = new ChatTalkSessionStaffRel();
            BeanUtils.copyProperties(talkSession, sessionStaffRel);

            sessionStaffRel.setId(IdUtil.getSnowflakeNextId());
            sessionStaffRel.setMerId(merId);
            sessionStaffRel.setStaffId(staffId);
            sessionStaffRel.setTalkSessionId(talkSession.getId());
            sessionStaffRel.setExpire(0);
            sessionStaffRel.setAuto(auto ? 1 : 0);
            sessionStaffRel.setCreateTime((int) (System.currentTimeMillis() / 1000L));
            sessionStaffRel.setLastTalkTime((int) (System.currentTimeMillis() / 1000L));

            chatTalkSessionStaffRelMapper.insertSelective(sessionStaffRel);
        }
        //
        refreshStaffSessionCount(merId, staffId);
    }

    public void updateById(ChatTalkSessionStaffRel update) {
        chatTalkSessionStaffRelMapper.updateByPrimaryKeySelective(update);
    }

    public int deleteByStaffIdWithEnd(@MerId Long merId, Long staffId) {
        return chatTalkSessionStaffRelMapper.deleteByStaffIdWithEnd(merId, staffId);
    }

    public ChatTalkSessionStaffRel getByConvIdAndSessionId(@MerId Long merId, String wxId, Long sessionId) {
        return chatTalkSessionStaffRelMapper.selectOneByConvIdAndSessionId(merId, wxId, sessionId);
    }

    public ChatTalkSessionStaffRel getByTalkId(@MerId Long merId, Long deviceUniqueId, Long talkSessionId) {

        ChatTalkSessionStaffRel sessionStaffRel = new ChatTalkSessionStaffRel();
        sessionStaffRel.setMerId(merId);
        sessionStaffRel.setDeviceUniqueId(deviceUniqueId);
        sessionStaffRel.setTalkSessionId(talkSessionId);

        return chatTalkSessionStaffRelMapper.selectOne(sessionStaffRel);
    }

    public Integer countByStaffId(@MerId Long merId, Long staffId) {
        return ObjectUtils.defaultIfNull(chatTalkSessionStaffRelMapper.countByStaffId(merId, staffId), 0);
    }

    public void cleanEnd(@MerId Long merId, Long id) {
        chatTalkSessionStaffRelMapper.updateWithCleanEndAndExpire(merId, id);
    }

    public void clean(@MerId Long merId, Long id) {
        chatTalkSessionStaffRelMapper.deleteByPrimaryKey(id);
    }

    public ChatTalkSessionStaffRel getByStaffIdAndTalkId(@MerId Long merId, Long deviceUniqueId, Long staffId, Long talkSessionId) {
        ChatTalkSessionStaffRel sessionStaffRel = new ChatTalkSessionStaffRel();
        sessionStaffRel.setMerId(merId);
        sessionStaffRel.setDeviceUniqueId(deviceUniqueId);
        sessionStaffRel.setTalkSessionId(talkSessionId);
        sessionStaffRel.setStaffId(staffId);

        return chatTalkSessionStaffRelMapper.selectOne(sessionStaffRel);
    }

    public void updateExpireTime(@MerId Long merId, ChatTalkSession talkSession, Long current, Long showExpireTime) {
        ChatTalkSessionStaffRel byTalkId = this.getByTalkId(merId, talkSession.getDeviceUniqueId(), talkSession.getId());
        if (Objects.isNull(byTalkId)) {
            return;
        }
        ChatTalkSessionStaffRel update = new ChatTalkSessionStaffRel();
        update.setId(byTalkId.getId());
        update.setExpireTime(current.intValue());
        update.setShowExpireTime(showExpireTime.intValue());
        update.setUpdateTime((int) (System.currentTimeMillis() / 1000L));
        chatTalkSessionStaffRelMapper.updateByPrimaryKeySelective(update);
    }
}
